/*
Sample HTML:
<div class="slide_container">
  <div group="client1" index="0" style="top: 0px;">
  </div>
  <div group="client1" index="0" style="top: 0px;">
  </div>
</div>

Sample JSON:


*/
//Event.observe(document, 'dom:loaded', initLoad, false);


var SlideShow = Class.create();

/* SLIDESHOW STUFF */
SlideShow.prototype = {
  /*
  slideshowElements is an array of elements used in the slideshow. The HTML must be set up properly prior to load.
  */
  initialize: function (containerID, options) {
    this.container = $(containerID);
    this.options = Object.extend({
      data: null,       /* optionally can pass image data as JSON. See docs for format + PHP code */

      captionId: null,  /* element where caption is displayed */
      positionId: null, /* element where position is displayed */
      jsonData: null,
      interval:5000,
      endshow: Prototype.emptyFunction(),
      initialState: "pause",  /* valid options play/pause */
      slider_track_id: null,  /* pass in ids corresponding to a properly set up slider track & handle.  slider.js from scriptaculous is required for this to work */
      slider_handle_id: null,
      groupAttribute: "group", 
      /*loading related */
			replaceImage	: "/images/blank.gif",					// Placeholder image to show instead of the image (best leave unchanged to this blank.gif!)
			loadingImage	: "/images/spinner.gif",				// Loading indicator
			onchange: Prototype.emptyFunction, //generic onchange function
			onplay: Prototype.emptyFunction, //generic onchange function
			onpause: Prototype.emptyFunction, //generic onchange function						
			onplaypause: Prototype.emptyFunction, //generic onchange function									
			TransitionOut: Effect.Fade,
			TransitionIn: Effect.Appear,
			transitionDuration: .5

    }, options || {});
    

    //console.log(start_index);
    this.loadQueue = new Array()    
    this.current_slide = -1;
    if (this.options.jsonData) {
     //build dom up out of json, and kick off loading...
 
      for (var i=0; i < parseInt(this.options.jsonData.length); i++) {
        var data = this.options.jsonData[i];
        var el = new Element('div', {'class': 'slide', 'style': 'display:none', 'index': i, 'caption': data.caption +"&nbsp;", 'group' : data.group});
        //this.loadQueue.unshift(i);
        this.container.insert(el);
      }
    }

    var hash = self.document.location.hash.substring(1);
    var start_index = 0;
    if (hash !== "") {
      var groups = $$('div['+ this.options.groupAttribute +'=' + hash + ']');
      //See if there's a client with the same name as hash    
      if (groups.length > 0) {
        start_index = parseInt(groups[0].getAttribute("index"));
      }
      else {
        start_index = 0;
      }
    }
    this.slides = this.container.immediateDescendants();
    
    //TODO: RE-ARRANGE QUEUE
    for (var i= start_index; i < parseInt(this.slides.length); i++) {
      this.loadQueue.unshift(i);
    }
    for (var i= 0; i < start_index; i++) {
      this.loadQueue.unshift(i);
    }
    
    if (this.options.jsonData) {
      this.loadImages();
    }
    this.container_height = this.container.getHeight();
    if ($(this.options.prevButton)){
      Event.observe(this.options.prevButton, "click", this.prev.bind(this));
    }
    if ($(this.options.nextButton)){
      Event.observe(this.options.nextButton, "click", this.next.bind(this));
    }
    if ($(this.options.playPause)){
      Event.observe(this.options.playPause, "click", this.playPause.bind(this));
    }
    this.bkeyhandler = this.keyhandler.bindAsEventListener(this);
    //Event.observe(document, 'keypress', this.bkeyhandler);
    

    if (this.slides.length > 0) {
      // init ImageLoading     
      //this.initLoader();
      this.state = this.options.initialState;
     
      if ( $(this.options.slider_track_id) != null && $(this.options.slider_handle_id) != null ) {         this.initSlider(start_index); 
         this.hasSlider = true;      }
      else {
        this.hasSlider = false; 
      };      this.go_to(start_index, true);    }
  },
  loadImages: function() {
    if (this.loadQueue.length > 0) {
      var i = this.loadQueue.pop();
      var img = this.options.jsonData[i];
      //console.log("src: " + this.options.jsonData.basedir + img.subdir + "/" + img.filename);
      //console.log(this.options.jsonData[i].params.rollover);

      this.slides[i].insert(new Element("img", {'src': this.options.jsonData.basedir + img.subdir + "/" + img.filename}));

      var obj = this;
      setTimeout(function () {obj.loadImages()},200);
    }
  },
  initSlider: function(start_index) {
      this.slider = new Control.Slider($(this.options.slider_handle_id), $(this.options.slider_track_id), {      range: $R(0, (this.slides.length-1) ),      values:$A($R(0,this.slides.length-1)),      sliderValue: start_index,      onSlide: function(v) {this.go_to(v, false); }.bind(this),      onChange: function(v) { }    });        
  },
  destroy: function() {
    this.options.endshow();
    //Event.stopObserving(document, 'keypress', this.bkeyhandler);
  },
  keyhandler: function(e){
    /*
    var code;
  
    if (!e) var e = window.event;
    if (e.keyCode) {
      code = e.keyCode;
    }
    else if (e.which) 
    {
      code = e.which;
    }
    switch (code) {
      case 27:
        this.destroy();
        break;
      case 37:
        this.prev();
        break;
      case 39:
        this.next();
        break;
    }
    */
  },

  playpause: function() {
    if (this.state == "play") {
      this.pause();
    }
    else {
      this.play();
    }
    this.options.onplaypause(this);
  },
  pause: function() {
    if (this.state == "play") {
      this.state = "pause";
      clearTimeout(this.nextCall);
      //update  (play/pause)
      this.options.onpause(this);
    }
  },

  play: function() {
    if (this.state == "pause") {
      this.state = "play";
      //update  (play/pause)
      this.nextCall = setTimeout(this.next.bind(this), 2000);
      this.options.onplay(this);
    }
  },
  go_to_clicked: function(e, i) {
    var img = e.currentTarget.getAttribute("img");
    var indx;
    for (var i=0; i < this.imagelinks.length; i++) {
      if (this.imagelinks[i] == img) {
        indx = i;
        break;
      }
    }
    this.go_to(indx);

    
  },
  go_to: function(slide, transition) {
    //this.options.ongo_to(slide, this.current_slide, 10, this.state);

    clearTimeout(this.nextCall);
    if (this.currentEffect) {
      if (this.currentEffect.cancel) 
      {
        this.currentEffect.cancel();
      }
    }
    if (this.current_slide != -1){
      if (transition == true) {
        new this.options.TransitionOut(this.slides[this.current_slide], {duration: this.options.transitionDuration});
        
      }
      else {
        this.slides[this.current_slide].hide(); 
      }
    }

    if (this.current_slide != -1){
      if (transition == true || this.options.TransitionOut != null) {
        new this.options.TransitionOut(this.slides[this.current_slide], {duration:  this.options.transitionDuration}); 
      }
      else {
        this.slides[this.current_slide].hide();
      }    }    //var effectFunction =     if (transition == true)
    {       new this.options.TransitionIn(this.slides[slide], {duration:  this.options.transitionDuration, afterFinish: effectFactory(this.slides[slide].getAttribute("effect"))} );    }
    else {
      this.slides[slide].show();
    }

    //new Effect.Appear(this.slides[slide]); //, {afterFinish: effectFactory(this.slides[slide].getAttribute("effect"))} );
    this.current_slide = slide;

    if (this.options.captionId) {
      $(this.options.captionId).update(this.slides[this.current_slide].getAttribute("caption"));
    }
    if (this.options.positionId) {
      $(this.options.positionId).update((this.current_slide+1) + "/" + this.slides.length);
    }
    if (this.state == "play") {
      var interval = this.slides[this.current_slide].getAttribute("interval");
      if (!interval) {
        interval = this.options.interval;
      }
      if (interval > 0) {
        this.nextCall = setTimeout(this.next.bind( this), interval);
      }
    }
    //call the onchange function!
    this.options.onchange(this);
  },
 
  next: function()
  { 
    if (this.current_slide + 1 == this.slides.length) {
      if (this.hasSlider) {
        this.slider.setValue(0);       
      }
      this.go_to(0, true);
    }
    else {
      if (this.hasSlider) {
        this.slider.setValue(this.current_slide+1); 
      }
      this.go_to(this.current_slide+1, true);
    }
  },
  prev: function()
  { 
    if (this.current_slide - 1 == -1) {
      if (this.hasSlider) {
        this.slider.setValue(this.slides.length - 1);
      }
      this.go_to(this.slides.length - 1, true);
    }
    else {
      if (this.hasSlider) {
        this.slider.setValue(this.current_slide - 1);
      }
      this.go_to(this.current_slide-1, true);       
    }
  }
};

function effectFactory(effectName) {
  switch(effectName) {
    case "pan-vert":
      return MoveUp;
      break;
    default:
      return Prototype.emptyFunction;
  }
}